package com.ruoyi.common.utils;

import com.ruoyi.common.exception.ServiceException;
import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

/**
 * RSA加密解密
 *
 * @author shuyan
 * 
 * 密钥对在线生成地址： http://web.chacuo.net/nHetrsakeypair
 **/
public class RsaUtils {

    /**
     * RSA 公钥
     */
    private static final String PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC02jqV5mfgmJ6+q8BcR7/Bp/PX\n" +
            "Gxv95+tcBFMaEidAY1ZRkMswnLW3rih6hwSs+m/qsJ8/GfZifvJ4mywr3REE7E7C\n" +
            "GK0+m2cUIB1xXzPNA58YIS7gp33sh5wHvojl5LSpajei7SVr7Q6bm5zC77x1uL8b\n" +
            "ahVbouUQgfrj6sMc1wIDAQAB";

    /**
     * Rsa 私钥
     */
    private static final String PRIVATE_KEY = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALTaOpXmZ+CYnr6r\n" +
            "wFxHv8Gn89cbG/3n61wEUxoSJ0BjVlGQyzCctbeuKHqHBKz6b+qwnz8Z9mJ+8nib\n" +
            "LCvdEQTsTsIYrT6bZxQgHXFfM80DnxghLuCnfeyHnAe+iOXktKlqN6LtJWvtDpub\n" +
            "nMLvvHW4vxtqFVui5RCB+uPqwxzXAgMBAAECgYEAgTAuj2vSIlcDdtK7i2/ZY920\n" +
            "yqDb4wkrUETqlAIJte3/+C4FZ4laKYan9bbDOUmAbtaSOwIxxXRHgq3d5Mt63qSl\n" +
            "hbdp+sB0UgIiAOJVcSopdQW811kijbcwJY83jdHl/Bj9JIngr5EldngT4APfwNC6\n" +
            "hUAnSIf3c2kMu+Kfa7ECQQDh4QCR7qDGx3MsNAyt+GKKLJLfxUwoXB0QYYlc6QH0\n" +
            "+w1Dw9k7UfhVproIlL3aWQ9xz7PEqrEIGDT7jTLSNGAZAkEAzPgf6mPlXtGg7a1/\n" +
            "o28HXlZhJaUdA3/DPW3Qu4HGrENmqiJHjFbemiaV/PN4J7Eql9OOBOx0HIO/00TJ\n" +
            "/F9CbwJBANmXAhGSKlbSc2Q1j7FXALXSUno1eTO36FeLXeOeoj/4R8Lruyulvu/j\n" +
            "eHojru/Ts0kTqDzfoUIG76MTVc2gnqECQAlvjsCSkreXvOnUJ+EVNmigX16FSF2l\n" +
            "3w4P5SEMq2G4xJwmcdbDFQJRrmvzpV9mZ4iPw6T0YbACXK1UKFxG4l8CQEXntNGD\n" +
            "TEoqItBd1WNMMSvAvQisAQklpJQVPSNd3L1iEBxKiwCqo/+KqMSxYJfHeTgsWfsz\n" +
            "PI8m4iLE1dq3h3Y=";

    /**
     * 私钥解密
     *
     * @param text 待解密的文本
     * @return 解密后的文本
     */
    public static String decryptByPrivateKey(String text) {
        return decryptByPrivateKey(PRIVATE_KEY, text);
    }


    /**
     * 私钥解密
     *
     * @param privateKeyString 私钥
     * @param text             待解密的文本
     * @return 解密后的文本
     */
    public static String decryptByPrivateKey(String privateKeyString, String text) {
        byte[] result = new byte[0];
        try {
            PKCS8EncodedKeySpec pkcs8EncodedKeySpec5 = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKeyString));
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec5);
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            result = cipher.doFinal(Base64.decodeBase64(text));
        } catch (Exception e) {
            throw new ServiceException(e.getMessage());
        }
        return new String(result);
    }


    /**
     * 公钥加密
     *
     * @param text 待加密的文本
     * @return 加密后的文本
     */
    public static String encryptByPublicKey(String text) {
        return encryptByPublicKey(PUBLIC_KEY, text);
    }

    /**
     * 公钥加密
     *
     * @param publicKeyString 公钥
     * @param text            待加密的文本
     * @return 加密后的文本
     */
    public static String encryptByPublicKey(String publicKeyString, String text) {
        byte[] result = new byte[0];
        try {
            X509EncodedKeySpec x509EncodedKeySpec2 = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyString));
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec2);
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            result = cipher.doFinal(text.getBytes());
        } catch (Exception e) {
            throw new ServiceException(e.getMessage());
        }
        return Base64.encodeBase64String(result);
    }


    /**
     * 构建RSA密钥对
     *
     * @return 生成后的公私钥信息
     */
    public static RsaKeyPair generateKeyPair() throws NoSuchAlgorithmException {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(1024);
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
        RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
        String publicKeyString = Base64.encodeBase64String(rsaPublicKey.getEncoded());
        String privateKeyString = Base64.encodeBase64String(rsaPrivateKey.getEncoded());
        return new RsaKeyPair(publicKeyString, privateKeyString);
    }

    /**
     * RSA密钥对对象
     */
    public static class RsaKeyPair {
        private final String publicKey;
        private final String privateKey;

        public RsaKeyPair(String publicKey, String privateKey) {
            this.publicKey = publicKey;
            this.privateKey = privateKey;
        }

        public String getPublicKey() {
            return publicKey;
        }

        public String getPrivateKey() {
            return privateKey;
        }
    }
}